package com.fingard.dsp.bank.directbank.gzelink01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.IStatement;
import com.fingard.dsp.bank.directbank.gzelink01.util.HttpUtils;
import com.fingard.dsp.bank.directbank.gzelink01.util.Md5;
import com.fingard.dsp.bank.reqrespobj.statement.ReqQryStatement;
import com.fingard.dsp.bank.reqrespobj.statement.RetAtsStatement;
import com.fingard.dsp.bank.reqrespobj.statement.TransState;
import com.fingard.dsp.bank.reqrespobj.statement.detail.RetAtsStatementDetail;
import com.fingard.text.StringHelper;

import java.io.BufferedReader;
import java.io.StringReader;
import java.util.Date;

/**
 * 广银联对账单
 */
public class GZELINK01Statement extends GZELINK01Base implements IStatement {
	public RetAtsStatement d_Qry_Statement(ReqQryStatement p_reqQrySttm) throws Exception {
		RetAtsStatement retAts = new RetAtsStatement(p_reqQrySttm);
		retAts.writeStart();
		
		String[] realtimeRecRespHeader = getRealTimeStatement(p_reqQrySttm, retAts);
		String realtimeRecTotalNum = getTotalNum(retAts.totalNum);

        String[] gatewayRespHeader = new String[]{"",""};
        String gatewayTotalNum = "0";
        if (!"F".equalsIgnoreCase(p_reqQrySttm.statementType)) {
            gatewayRespHeader = getGatewayStatement(p_reqQrySttm, retAts);
            gatewayTotalNum = getTotalNum(retAts.totalNum);
        }
		if ("-1".equals(realtimeRecRespHeader[0]) && "-1".equals(gatewayRespHeader[0])) {
			retAts.writeRespCode("-1");
        	retAts.writeRespInfo(StringHelper.joinNotEmpty("\r\n", "单笔实时对账单获取失败，原因:" + realtimeRecRespHeader[1], "网关/一码付对账单获取失败，原因:" + gatewayRespHeader[1]));
		} else {
			if (retAts.getWrittenRdCount() == 0) {
				retAts.writeRespCode("0");
				String respInfo = realtimeRecRespHeader[1];
				if (StringHelper.isNullOrEmpty(respInfo)) {
					respInfo = gatewayRespHeader[1];
				}
				if (StringHelper.isNullOrEmpty(respInfo)) {
					respInfo = "交易为空!";
				}
				retAts.writeRespInfo(respInfo);
			} else {
				// 获取成功时写入总笔数
				retAts.isWritedTotalNum(String.valueOf(Integer.parseInt(realtimeRecTotalNum) + Integer.parseInt(gatewayTotalNum)));
			}
		}
		
		retAts.writeEnd();
		return retAts;
	}

    /**
     * 单笔实时代收付对账单
     *
     * @param p_reqQrySttm
     * @param retAts
     * @return
     * @throws Exception
     */
    private String[] getRealTimeStatement(ReqQryStatement p_reqQrySttm, RetAtsStatement retAts) throws Exception {
        String[] tmpRespHeader = new String[]{"",""};

        String tmpRespCode = "";
        String tmpRespInfo = "";

        retAts.totalNum = "0";
        int totalNum = 0;

        try{
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqQrySttm.actNum, "");
            if (actItem != null) {
                //代收为S，代付为F
                String transCode = "";
                if (StringHelper.hasAnyChar(actItem.billType)) {
                    if ("S".equalsIgnoreCase(actItem.billType)) {
                        transCode = "S";
                    } else if ("F".equalsIgnoreCase(actItem.billType)) {
                        transCode = "F";
                    } else {
                        transCode = "S,F";
                    }
                } else {
                    if ("F".equalsIgnoreCase(p_reqQrySttm.statementType)) {
                        transCode = "F";
                    } else if ("S".equalsIgnoreCase(p_reqQrySttm.statementType)) {
                        transCode = "S";
                    } else {
                        transCode = "S,F";
                    }
                }

                String statementRec = "";
                for (String tranCode : transCode.split(",")) {
                    String settDate = Format.Date8Format.format(p_reqQrySttm.getBusDate());
                    String settNo = "01";
                    String sfType = tranCode;
                    String userName = actItem.userCode;
                    String merchantID = actItem.merchantId;
                    String reqTime = Format.DateTime14Format.format(new Date());

                    // 清算日期|清算场次|用户名|商户号|请求时间
                    String signData = settDate + "|" + settNo  + "|" + userName + "|" + merchantID + "|" + reqTime;

                    WriteBankLogLn2("广银联单笔实时收付对账单签名原始数据:\r\n" + signData);

                    String reqData = "SETT_DATE=" + settDate + "&SETT_NO=" + settNo + "&SF_TYPE=" + sfType
                            + "&USER_NAME=" + userName + "&MERCHANT_ID=" + merchantID
                            + "&REQ_TIME=" + reqTime + "&SIGNED_MSG=" + signMsg(signData, actItem);

                    String[] tmpStrRet = sendDataToBank(reqData);

                    if (tmpStrRet[0].length() == 0) {
                        WriteBankLogLn2("广银联单笔实时收付对账单响应数据:\r\n" + tmpStrRet[1]);
                        if (tmpStrRet[1].length() == 0) {
                            tmpRespCode = "-1";
                            tmpRespInfo = "广银联实时收款对账单返回内容为空,请联系广银联相关技术人员!";
                        } else if (tmpStrRet[1].indexOf("|") > 0) {
                            StringReader strreader = new StringReader(tmpStrRet[1]);
                            BufferedReader tmpreader = new BufferedReader(strreader);

                            while(true) {
                                String eachline = tmpreader.readLine();
                                if(eachline == null){
                                    break;
                                }

                                String[] eachNodes = eachline.split("\\|");
                                RetAtsStatementDetail tmpRetDetail = new RetAtsStatementDetail();

                                if ("0".equals(eachNodes[5]) || "1".equals(eachNodes[5])) {
                                    if (eachNodes.length == 10) {
                                        // A格式
                                        if (StringHelper.hasAnyChar(eachNodes[1].trim())) {
                                            tmpRetDetail.reqBatchNO = eachNodes[0].trim();
                                            tmpRetDetail.askNumber = eachNodes[1].trim();
                                        } else {
                                            tmpRetDetail.askNumber = eachNodes[0].trim();
                                        }
                                    } else if (eachNodes.length == 9) {
                                        // B格式
                                        if (StringHelper.hasAnyChar(eachNodes[1].trim())) {
                                            tmpRetDetail.reqBatchNO = eachNodes[0].trim();
                                            tmpRetDetail.askNumber = eachNodes[1].trim();
                                        } else {
                                            tmpRetDetail.askNumber = eachNodes[0].trim();
                                        }
                                    } else if (eachNodes.length == 15) {
                                        // C格式
                                        String askNumber = eachNodes[0].trim();
                                        String custUserId = eachNodes[9].trim();
                                        if (custUserId.length() > 0 && askNumber != custUserId) {
                                            tmpRetDetail.askNumber = custUserId;
                                            tmpRetDetail.reqBatchNO = askNumber;
                                        } else if (custUserId.length() > 0) {
                                            tmpRetDetail.askNumber = custUserId;
                                        } else {
                                            tmpRetDetail.askNumber = askNumber;
                                        }
                                    } else {
                                        tmpRespCode = "-1";
                                        tmpRespInfo = "广银联对账单返回明细列数非法";
                                    }

                                    tmpRetDetail.oppAct = eachNodes[2].trim();
                                    tmpRetDetail.oppActName = eachNodes[3].trim();
                                    tmpRetDetail.amount = eachNodes[4].trim();
                                    tmpRetDetail.busTime = Format.DateTime14Format.format(p_reqQrySttm.getBusDate());
                                    if ("0".equals(eachNodes[5])) {
                                        tmpRetDetail.transState = TransState.Success;
                                    } else if ("1".equals(eachNodes[5])) {
                                        tmpRetDetail.transState = TransState.Fail;
                                    }
                                    tmpRetDetail.oppBank = null;
                                    tmpRetDetail.bkSeq = null;
                                    if ("F".equalsIgnoreCase(tranCode) && "ORA".equals(eachNodes[7])) {
                                        totalNum++;
                                        tmpRetDetail.cdFlag = "27";
                                        retAts.writeRetDetail(tmpRetDetail);
                                    } else if ("S".equalsIgnoreCase(tranCode) && "DOA".equals(eachNodes[7])) {
                                        totalNum++;
                                        tmpRetDetail.cdFlag = "22";
                                        retAts.writeRetDetail(tmpRetDetail);
                                    }
                                } else if ("0".equals(eachNodes[6]) || "1".equals(eachNodes[6])) {
                                    if (eachNodes.length == 16) {
                                        String askNumber = eachNodes[0].trim();
                                        String custUserId = eachNodes[10].trim();
                                        if (custUserId.length() > 0 && askNumber != custUserId) {
                                            tmpRetDetail.askNumber = custUserId;
                                            tmpRetDetail.reqBatchNO = askNumber;
                                        } else if (custUserId.length() > 0) {
                                            tmpRetDetail.askNumber = custUserId;
                                        } else {
                                            tmpRetDetail.askNumber = askNumber;
                                        }
                                        tmpRetDetail.oppAct = eachNodes[3].trim();
                                        tmpRetDetail.oppActName = eachNodes[4].trim();
                                        tmpRetDetail.amount = eachNodes[5].trim();
                                        tmpRetDetail.busTime = Format.DateTime14Format.format(p_reqQrySttm.getBusDate());
                                        if ("0".equals(eachNodes[6])) {
                                            tmpRetDetail.transState = TransState.Success;
                                        } else if ("1".equals(eachNodes[6])) {
                                            tmpRetDetail.transState = TransState.Fail;
                                        }
                                        tmpRetDetail.oppBank = null;
                                        tmpRetDetail.bkSeq = null;
                                        if ("F".equalsIgnoreCase(tranCode) && "ORA".equals(eachNodes[8])) {
                                            totalNum++;
                                            tmpRetDetail.cdFlag = "27";
                                            retAts.writeRetDetail(tmpRetDetail);
                                        } else if ("S".equalsIgnoreCase(tranCode) && "DOA".equals(eachNodes[8])) {
                                            totalNum++;
                                            tmpRetDetail.cdFlag = "22";
                                            retAts.writeRetDetail(tmpRetDetail);
                                        }
                                    } else {
                                        tmpRespCode = "-1";
                                        tmpRespInfo = "广银联对账单返回明细列数非法";
                                    }
                                }
                            }
                        } else {
                            tmpRespCode = "-1";
                            tmpRespInfo = tmpStrRet[1].trim();
                        }
                    } else {
                        tmpRespCode = "-1";
                        tmpRespInfo = tmpStrRet[1];
                    }
                }
            } else {
                tmpRespHeader[0] = "-1";
                tmpRespHeader[1] = "未找到账号:[" + p_reqQrySttm.actNum + "]商户配置信息,请检查config/portfiles/GZELINK01/config.xml中'actSet'配置节点信息是否正确!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRespCode = "-1";
            tmpRespInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.totalNum = String.valueOf(totalNum);
        tmpRespHeader[0] = tmpRespCode;
        tmpRespHeader[1] = tmpRespInfo;

        return tmpRespHeader;
    }
	
	/**
	 * 网关/一码付对账单
	 * 
	 * @param p_reqQrySttm
	 * @param retAts
	 * @return
	 * @throws Exception
	 */
	private String[] getGatewayStatement(ReqQryStatement p_reqQrySttm, RetAtsStatement retAts) throws Exception {
		String[] respHeader = new String[]{"",""};
		
		String tmpRespCode = "";
		String tmpRespInfo = "";
		
		retAts.totalNum = "0";
		int totalNum = 0;
		
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_reqQrySttm.actNum, "unifiedorder");
			if (actItem != null) {
				String pwd = actItem.userFlag;
				pwd = Md5.md5(pwd, getCharset());

				StringBuilder reqPostData = new StringBuilder();
				reqPostData.append("TranType=" + "100");
				reqPostData.append("&JavaCharset=" + getCharset());
				reqPostData.append("&Version=" + "V60");
				reqPostData.append("&UserId=" + actItem.userCode);
				reqPostData.append("&Pwd=" + pwd);
				reqPostData.append("&MerId=" + actItem.merchantId);
				reqPostData.append("&PayStatus=" + "1");
				reqPostData.append("&ShoppingTime=" + Format.DateTimeFormat.format(p_reqQrySttm.getBusDate()));
				reqPostData.append("&BeginTime=");
				reqPostData.append("&EndTime=");
				reqPostData.append("&OrderNo=");
				
				WriteBankLogStep2(reqPostData.toString());
				String postUrl = bankFront.getUrl("qryGatewayStatement");
                WriteBankUrlLogLn(postUrl);
				if (StringHelper.isNullOrEmpty(postUrl)) {
                    respHeader[0] = "-1";
                    respHeader[1] = "网关/一码付对账单地址为空,请检查config/BankFront.xml中'qryGatewayStatement'节点配置信息!";
                    return respHeader;
                }

				String tmpStrRet = new HttpUtils().doHttpPost(postUrl, reqPostData.toString(), getCharset());
				WriteBankLogStep3(tmpStrRet);
				
				// 错误返回：Code=5062&Message=用户不存在，系统未授权！
				if (tmpStrRet.indexOf("Code=") >= 0) {
					String[] respMsg = tmpStrRet.split("&");
					tmpRespCode = "-1";
					tmpRespInfo = respMsg[1].split("=")[1];
	        	} else if (tmpStrRet.indexOf("\n") > 0) {
	        		StringReader strReader = new StringReader(tmpStrRet);
					BufferedReader tmpReader = new BufferedReader(strReader);
					
					String line = tmpReader.readLine();
					if(line == null){
						tmpRespCode = "-1";
						tmpRespInfo = "本日无交易";
					} else {
						totalNum++;
						while (line.length() < tmpStrRet.length()) {
							String eachline = tmpReader.readLine();
							if(eachline == null){
								break;
							}
							totalNum++;
							line += eachline;
						}
					}
					
					StringReader tmpStrReader = new StringReader(tmpStrRet);
					BufferedReader tmpBuferReader = new BufferedReader(tmpStrReader);
					
					while(true) {
						String eachline = tmpBuferReader.readLine();
						if(eachline == null){
							break;
						}
						
						String[] eachNodes = eachline.split("\\\\n");
						
						RetAtsStatementDetail p_retDetail = new RetAtsStatementDetail();
						
						if (StringHelper.hasAnyChar(eachNodes[2])) {
							p_retDetail.askNumber = eachNodes[2];
						}
						
						if (StringHelper.hasAnyChar(eachNodes[1])) {
							p_retDetail.amount = eachNodes[1];
						}
						
						p_retDetail.cdFlag = "22";
						
						if (StringHelper.hasAnyChar(eachNodes[0])) {
							p_retDetail.busTime = Format.DateTime14Format.format(Format.Date8Format.parse(eachNodes[0]));
						}

	    				p_retDetail.transState = TransState.Success;
		        		retAts.writeRetDetail(p_retDetail);
					}
				} else {
	        		tmpRespCode = "-1";
	        		tmpRespInfo = tmpStrRet;
	        	}
			} else {
				tmpRespCode = "-1";
                tmpRespInfo = "未找到账号:[" + p_reqQrySttm.actNum + "]商户配置信息,请检查config/portfiles/GZELINK01/config.xml中'actSet'配置节点信息是否正确!";
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRespCode = "-1";
			tmpRespInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}
		
		retAts.totalNum = String.valueOf(totalNum);
		respHeader[0] = tmpRespCode;
		respHeader[1] = tmpRespInfo;
		
		return respHeader;
	}
}